#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time   : 2021/3/26 20:07
# @Author : cjw

# chapter_url = 'http://dushu.baidu.com/api/pc/getCatalog?data={"book_id":"4306063500"}'
# content_url = 'http://dushu.baidu.com/api/pc/getChapterContent?' \
#               'data={"book_id":"4306063500","cid":"4306063500|11348571","need_bookinfo":1}'
import requests
import asyncio
import aiohttp
import aiofiles
import json
import time

"""
1、同步操作：获取小说章节的cid和名称
2、异步操作：获取小说章节的内容
"""
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36'
}


def get_catalog(url: str):
    """
    同步操作：获取小说章节的cid和名称
    :return:
    """
    resp = requests.get(url, headers=headers)
    chapter_dict = resp.json()['data']['novel']['items']
    cid_list = [chapter['cid'] for chapter in chapter_dict]
    resp.close()
    return cid_list


async def download_chapter(cid: str, book_id: str):
    """
    异步操作：获取小说章节的内容
    :param cid: 章节的cid
    :param book_id: 小说的id
    :param title: 章节的标题
    :return:
    """
    # url组装
    data = {
        'book_id': book_id,
        'cid': f'{book_id}|{cid}',
        'need_bookinfo': 1
    }
    data = json.dumps(data)
    content_url = f'http://dushu.baidu.com/api/pc/getChapterContent?data={data}'

    # 随机等待时间
    # time_sleep = round(uniform(0.5, 2), 2)
    # sleep(time_sleep)

    # 请求url，下载小说章节内容
    async with aiohttp.ClientSession() as session:
        # 发送请求章节的内容
        async with session.get(content_url, headers=headers) as resp:
            # 获取章节内容，写入对应的文件中
            dic = await resp.json()
            novel = dic['data']['novel']
            async with aiofiles.open(f'./novel/{novel["chapter_title"]}.txt', 'w', encoding='utf-8') as f:
                await f.write(novel['content'])
                print(f'成功下载章节内容：{novel["chapter_title"]}')


async def main(url: str, book_id: str):
    cid_list = get_catalog(url)
    # 任务加载
    tasks = [asyncio.create_task(download_chapter(cid, book_id)) for cid in cid_list]
    await asyncio.wait(tasks)


if __name__ == '__main__':
    novel_id = '4306063500'
    chapter_url = 'http://dushu.baidu.com/api/pc/getCatalog?data={"book_id":"' + novel_id + '"}'
    # cids = get_catalog(chapter_url)
    t1 = time.time()
    asyncio.run(main(chapter_url, novel_id))
    t2 = time.time()
    print(f'下载耗时：{round((t2 - t1), 2)}s')
